package cn.itsource.ymcc.service.impl;

import cn.itsource.ymcc.constant.NoticeConstant;
import cn.itsource.ymcc.doc.CourseDoc;
import cn.itsource.ymcc.domain.*;
import cn.itsource.ymcc.dto.CourseDTO;
import cn.itsource.ymcc.dto.CourseNoticeDto;
import cn.itsource.ymcc.exception.CustomException;
import cn.itsource.ymcc.exception.ErrorCode;
import cn.itsource.ymcc.feign.client.CourseDocFeignClient;
import cn.itsource.ymcc.mapper.CourseMapper;
import cn.itsource.ymcc.result.JSONResult;
import cn.itsource.ymcc.service.*;
import cn.itsource.ymcc.util.AssertUtil;
import com.baomidou.mybatisplus.service.impl.ServiceImpl;
import lombok.extern.slf4j.Slf4j;
import org.apache.rocketmq.client.producer.SendResult;
import org.apache.rocketmq.client.producer.SendStatus;
import org.apache.rocketmq.spring.core.RocketMQTemplate;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.Assert;

import java.util.List;

/**
 * <p>
 *  服务实现类
 * </p>
 *
 * @author gwk
 * @since 2023-08-04
 */
@Service
@Slf4j
public class CourseServiceImpl extends ServiceImpl<CourseMapper, Course> implements ICourseService {


    @Autowired
    private ICourseDetailService detailService;

    @Autowired
    private ICourseMarketService marketService;

    @Autowired
    private ICourseResourceService resourceService;

    @Autowired
    private ITeacherService teacherService;

    @Override
    @Transactional(propagation = Propagation.SUPPORTS,readOnly = false)
    public void save(CourseDTO courseDTO) {
        //1. 参数校验 -- JS303
        Course course = courseDTO.getCourse();
        CourseMarket courseMarket = courseDTO.getCourseMarket();
        CourseDetail courseDetail = courseDTO.getCourseDetail();
        CourseResource courseResource = courseDTO.getCourseResource();
        List<Long> teacharIds = courseDTO.getTeacharIds();

        //2. 业务校验 -- 暂时没有
        //3. 保存 -- 先保存 Course
        // 根据老师id ,查询对应的老师
        List<Teacher> teachers = teacherService.selectBatchIds(teacharIds);
        Assert.notNull(teachers, "没有找到对应的老师");
        StringBuilder sb = new StringBuilder();
        for (Teacher teacher : teachers) {
            sb.append(teacher.getName()).append(",");
        }
        // 设置老师名称
        course.setTeacherNames(sb.toString());
        // 制定其他属性
        course.setStatus(0);
        //TODO 先用假的的管理员，添加课程，后面通过Token获取
        course.setLoginId(1L);
        course.setLoginUserName("张三");

        insert(course);
        //3.2 获取到courseid ，在保存课程详情，营销，资源，课程老师中间表
        courseDetail.setId(course.getId());
        detailService.insert(courseDetail);

        courseMarket.setId(course.getId());
        marketService.insert(courseMarket);

        courseResource.setCourseId(course.getId());
        resourceService.insert(courseResource);

        //添加中间表数据
        baseMapper.insertToCourserTeacher(course.getId(),teacharIds);

    }

    @Autowired
    private CourseDocFeignClient courseDocFeignClient;

    @Autowired
    private RocketMQTemplate rocketMQTemplate;


    @Override
    public void onLineCourse(Long courseID) {
        //1. 参数校验
        AssertUtil.isNotNull(courseID, ErrorCode.COURSE_ID_EMPTY);
        //2. 查询课程信息 课程应该存在切未上线
        Course course = selectById(courseID);
        AssertUtil.isNotNull(course, ErrorCode.COURSE_NOT_EXIST);
        // 断言课程是未上线的状态
        AssertUtil.isTrue(Course.STATUS_OFFLINE.equals(course.getStatus()),ErrorCode.COURSE_HAD_ONLINE);

        //3. 修改课程的上下线状态
        course.setStatus(Course.STATUS_ONLINE);
        updateById(course);

        //4. 查询课程的其他信息 课程营销，简介，
        CourseDetail courseDetail = detailService.selectById(courseID);
        CourseMarket courseMarket = marketService.selectById(courseID);

        //5. 封装CouseDoc对象
        CourseDoc courseDoc = new CourseDoc();
        BeanUtils.copyProperties(course,courseDoc);
        BeanUtils.copyProperties(courseDetail,courseDoc);
        BeanUtils.copyProperties(courseMarket,courseDoc);

        //6. 添加到ES中 --》 OpenFeign
        JSONResult result = courseDocFeignClient.online(courseDoc);

        //7. 判断 添加到ES是否成功，是否需要回滚数据的状态
        if(!result.isSuccess()){
            //8. 修改课程的上下线状态 回滚数据;
            course.setStatus(Course.STATUS_OFFLINE);
            updateById(course);

            throw new CustomException(ErrorCode.COURSE_ONLINE_FAIL);
        }

        // 用邮寄，短信，站内信，通知用户课程上线
        CourseNoticeDto courseNoticeDto = new CourseNoticeDto();

        courseNoticeDto.setTitle(courseDoc.getName());
        courseNoticeDto.setPath(String.format(NoticeConstant.COURSE_PATH,course.getId()));

         // 使用同步通知效率太低，我们通过MQ转换为异步操作
        SendResult sendResult = rocketMQTemplate.syncSend(NoticeConstant.TOPIC, courseNoticeDto);
        if (sendResult.getSendStatus()== SendStatus.SEND_OK){
            // 发送成功
            log.info("异步通知课程上线成功");
        }else {
            // 发送失败
            log.error("异步通知课程上线失败");
        }
    }

        // 发送站内信)
//        sendSMS(courseNoticeDto);
//        sendEmail(courseNoticeDto);
//        sendStation(courseNoticeDto);
}
